<!DOCTYPE html>
<html>
<head>
    <title>Social Media Card Cropper</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.css">
    <style>
        body {
            font-family: system-ui, -apple-system, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background: #f5f5f5;
            color: #333;
        }
        .container {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .drop-zone {
            border: 2px dashed #ccc;
            border-radius: 4px;
            padding: 40px 20px;
            text-align: center;
            margin-bottom: 20px;
            background: #fafafa;
            cursor: pointer;
            transition: all 0.2s ease;
        }
        .drop-zone:hover {
            border-color: #999;
            background: #f2f2f2;
        }
        .drop-zone.dragover {
            border-color: #0066cc;
            background: #e6f2ff;
        }
        .img-container {
            max-width: 100%;
            margin-bottom: 20px;
        }
        #image {
            display: block;
            max-width: 100%;
        }
        .preview-container {
            margin-top: 20px;
            padding: 16px;
            background: #fafafa;
            border-radius: 8px;
            border: 1px solid #eee;
        }
        #preview {
            width: 100%;
            max-width: 600px;
            margin: 0 auto;
            display: block;
            border-radius: 4px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }
        .download-btn {
            display: inline-block;
            padding: 10px 20px;
            background: #0066cc;
            color: white;
            text-decoration: none;
            border-radius: 4px;
            margin-top: 10px;
            transition: background 0.2s;
            font-weight: 500;
            border: none;
            cursor: pointer;
        }
        .download-btn:hover {
            background: #0052a3;
        }
        .hidden {
            display: none;
        }
        .controls {
            margin-bottom: 20px;
            padding: 15px;
            background: #f9f9f9;
            border-radius: 6px;
            border: 1px solid #eee;
        }
        .aspect-controls {
            margin-bottom: 15px;
        }
        .zoom-controls {
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 15px 0;
            gap: 10px;
        }
        .control-btn {
            background: #f0f0f0;
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 5px 12px;
            cursor: pointer;
            transition: all 0.2s;
            font-weight: 500;
        }
        .control-btn:hover {
            background: #e0e0e0;
            border-color: #ccc;
        }
        .zoom-value {
            width: 50px;
            text-align: center;
            font-weight: 500;
        }
        .color-picker {
            display: flex;
            align-items: center;
            margin-top: 15px;
        }
        #backgroundColor {
            width: 40px;
            height: 40px;
            padding: 0;
            border: 1px solid #ddd;
            border-radius: 4px;
            margin-left: 8px;
            cursor: pointer;
        }
        .help-text {
            font-size: 13px;
            color: #666;
            margin-top: 5px;
        }
        .options-container {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
        }
        .option-group {
            flex: 1;
            min-width: 200px;
        }
        label {
            font-weight: 500;
        }
        @media (max-width: 600px) {
            .controls {
                padding: 10px;
            }
            .options-container {
                gap: 10px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Social Media Card Cropper</h1>
        <p>Drop an image or click to select. Create perfect social media cards with custom backgrounds.</p>
        
        <div class="controls">
            <div class="options-container">
                <div class="option-group">
                    <label>Aspect Ratio:</label>
                    <div class="aspect-controls">
                        <label style="margin-right: 10px; display: block; margin-top: 8px;">
                            <input type="radio" name="aspectRatio" value="2" checked> 2:1 (Twitter/LinkedIn)
                        </label>
                        <label style="margin-right: 10px; display: block; margin-top: 8px;">
                            <input type="radio" name="aspectRatio" value="1.91"> 1.91:1 (Facebook)
                        </label>
                        <label style="margin-right: 10px; display: block; margin-top: 8px;">
                            <input type="radio" name="aspectRatio" value="1.4"> 1.4:1 (Substack)
                        </label>
                        <label style="display: block; margin-top: 8px;">
                            <input type="radio" name="aspectRatio" value="1"> 1:1 (Instagram)
                        </label>
                    </div>
                </div>
                
                <div class="option-group">
                    <div class="color-picker">
                        <label for="backgroundColor">Background color:</label>
                        <input type="color" id="backgroundColor" value="#ffffff">
                    </div>
                    
                    <div style="margin-top: 15px;">
                        <button id="resetBtn" class="control-btn">Reset Image</button>
                        <span id="zoomValue" class="zoom-value" style="margin-left: 10px;">100%</span>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="drop-zone" id="dropZone">
            <div>
                <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" style="color: #999; margin-bottom: 10px;">
                    <path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7"></path>
                    <line x1="16" y1="5" x2="22" y2="5"></line>
                    <line x1="19" y1="2" x2="19" y2="8"></line>
                    <circle cx="9" cy="9" r="2"></circle>
                    <path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"></path>
                </svg>
            </div>
            Drop image here, click to select, or paste from clipboard
            <div class="help-text">Supports JPG, PNG, GIF, and WebP formats</div>
            <input type="file" id="fileInput" accept="image/*" class="hidden">
        </div>

        <div class="img-container">
            <img id="image" class="hidden">
        </div>
        
        <div class="zoom-controls hidden" id="zoomControlsContainer">
            <button id="zoomOutBtn" class="control-btn">−</button>
            <button id="zoomInBtn" class="control-btn">+</button>
        </div>

        <div class="preview-container hidden" id="previewContainer">
            <h3>Preview</h3>
            <img id="preview">
            <div id="dimensionsInfo" style="text-align: center; margin-top: 10px; font-size: 14px; color: #666;"></div>
            <div style="text-align: center; margin-top: 15px;">
                <a href="#" id="downloadBtn" class="download-btn">Download Social Media Card</a>
            </div>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.js"></script>
    <script>
        let cropper = null;
        let cropperData = null;
        let zoomValue = 1;
        
        const dropZone = document.getElementById('dropZone');
        const fileInput = document.getElementById('fileInput');
        const backgroundColor = document.getElementById('backgroundColor');
        const zoomInBtn = document.getElementById('zoomInBtn');
        const zoomOutBtn = document.getElementById('zoomOutBtn');
        const zoomValueDisplay = document.getElementById('zoomValue');
        const resetBtn = document.getElementById('resetBtn');
        const zoomControlsContainer = document.getElementById('zoomControlsContainer');
        
        const image = document.getElementById('image');
        const preview = document.getElementById('preview');
        const previewContainer = document.getElementById('previewContainer');
        const downloadBtn = document.getElementById('downloadBtn');

        // Handle paste events
        document.addEventListener('paste', (e) => {
            e.preventDefault();
            const items = (e.clipboardData || e.originalEvent.clipboardData).items;
            for (const item of items) {
                if (item.type.indexOf('image') === 0) {
                    const file = item.getAsFile();
                    handleFile(file);
                    break;
                }
            }
        });

        // Handle drag and drop
        dropZone.addEventListener('dragover', (e) => {
            e.preventDefault();
            dropZone.classList.add('dragover');
        });

        dropZone.addEventListener('dragleave', () => {
            dropZone.classList.remove('dragover');
        });

        dropZone.addEventListener('drop', (e) => {
            e.preventDefault();
            dropZone.classList.remove('dragover');
            handleFile(e.dataTransfer.files[0]);
        });

        // Handle click to select
        dropZone.addEventListener('click', () => {
            fileInput.click();
        });

        fileInput.addEventListener('change', (e) => {
            if (e.target.files.length) {
                handleFile(e.target.files[0]);
            }
        });
        
        // Reset button
        resetBtn.addEventListener('click', () => {
            if (cropper) {
                cropper.reset();
                zoomValue = 1;
                updateZoomDisplay();
                updatePreview();
            }
        });
        
        // Listen for aspect ratio changes and update the cropper
        document.querySelectorAll('input[name="aspectRatio"]').forEach(radio => {
            radio.addEventListener('change', () => {
                if (cropper) {
                    // Save the current zoom level and other data
                    const currentZoom = zoomValue;
                    
                    // Reinitialize cropper with new aspect ratio
                    initCropper(true);
                    
                    // Restore zoom after initialization
                    setTimeout(() => {
                        zoomValue = currentZoom;
                        updateZoomDisplay();
                        cropper.zoomTo(currentZoom);
                    }, 100);
                }
            });
        });
        
        // Listen for background color changes and update the preview
        backgroundColor.addEventListener('change', () => {
            updatePreview();
        });
        
        // Handle zoom buttons
        zoomInBtn.addEventListener('click', () => {
            if (cropper) {
                // Smaller increment for zooming in
                zoomValue = Math.min(zoomValue + 0.02, 3);
                updateZoomDisplay();
                cropper.zoomTo(zoomValue);
            }
        });
        
        zoomOutBtn.addEventListener('click', () => {
            if (cropper) {
                // Extra small decrement for zooming out, with smaller steps at lower zoom levels
                let zoomDecrement = 0.02;
                
                // Use even smaller decrements for small zoom values
                if (zoomValue < 0.2) {
                    zoomDecrement = 0.005;
                } else if (zoomValue < 0.5) {
                    zoomDecrement = 0.01;
                }
                
                zoomValue = Math.max(zoomValue - zoomDecrement, 0.01);
                updateZoomDisplay();
                cropper.zoomTo(zoomValue);
                
                // Force update canvas size to allow zooming out beyond image boundaries
                const canvasData = cropper.getCanvasData();
                if (zoomValue < 0.3) {
                    // Apply more aggressive canvas scaling for very small zoom levels
                    // Smaller scale factor for smoother transitions
                    const scaleFactor = zoomValue < 0.1 ? 0.98 : 0.99;
                    
                    cropper.setCanvasData({
                        width: canvasData.width * scaleFactor,
                        height: canvasData.height * scaleFactor,
                        left: canvasData.left + (canvasData.width - canvasData.width * scaleFactor) / 2,
                        top: canvasData.top + (canvasData.height - canvasData.height * scaleFactor) / 2
                    });
                }
            }
        });
        
        function updateZoomDisplay() {
            // Show zoom percentage with 1 decimal place for smaller values
            let displayValue = Math.round(zoomValue * 100);
            if (zoomValue < 0.1) {
                // Show more precision for very small values
                displayValue = (zoomValue * 100).toFixed(1);
            }
            zoomValueDisplay.textContent = `${displayValue}%`;
        }

        function handleFile(file) {
            if (!file || !file.type.startsWith('image/')) {
                alert('Please select a valid image file.');
                return;
            }

            const reader = new FileReader();
            reader.onload = (e) => {
                image.src = e.target.result;
                image.classList.remove('hidden');
                zoomControlsContainer.classList.remove('hidden');
                
                // Reset zoom value to default
                zoomValue = 1;
                updateZoomDisplay();
                
                initCropper();
            };
            reader.readAsDataURL(file);
        }

        function initCropper(preserveData = false) {
            if (cropper) {
                // Store data if needed
                if (preserveData) {
                    cropperData = cropper.getData();
                }
                
                cropper.destroy();
            }

            // Get the selected aspect ratio
            const aspectRatioValue = document.querySelector('input[name="aspectRatio"]:checked').value;
            const ratio = parseFloat(aspectRatioValue);

            cropper = new Cropper(image, {
                aspectRatio: ratio,
                viewMode: 0, // Changed to 0 to allow for unlimited movement
                dragMode: 'move',
                autoCropArea: 0.9,
                restore: false,
                guides: true,
                center: true,
                highlight: false,
                cropBoxMovable: true,
                cropBoxResizable: true,
                toggleDragModeOnDblclick: false,
                minCropBoxWidth: 100,
                minCropBoxHeight: 100,
                ready: function() {
                    // If we need to restore data
                    if (preserveData && cropperData) {
                        // Set the crop box data first
                        setTimeout(() => {
                            cropper.setData(cropperData);
                        }, 50);
                    }
                    
                    // Initial preview update
                    updatePreview();
                },
                zoom: function(e) {
                    // Update zoom value when zooming from cropper
                    zoomValue = e.detail.ratio;
                    updateZoomDisplay();
                },
                crop: updatePreview
            });
        }

        function updatePreview() {
            if (!cropper) return;

            // Create a larger canvas with the background color
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            
            // Get the selected aspect ratio
            const aspectRatioValue = document.querySelector('input[name="aspectRatio"]:checked').value;
            const ratio = parseFloat(aspectRatioValue);
            
            // Set canvas dimensions to the desired aspect ratio
            if (ratio === 2) {
                canvas.width = 1200;
                canvas.height = 600;
            } else if (ratio === 1.91) {
                canvas.width = 1200;
                canvas.height = 628;
            } else if (ratio === 1.4) {
                canvas.width = 1400;
                canvas.height = 1000;
            } else if (ratio === 1) {
                canvas.width = 1080;
                canvas.height = 1080;
            } else {
                canvas.width = 1200;
                canvas.height = 1200 / ratio;
            }
            
            // Fill with background color
            ctx.fillStyle = backgroundColor.value;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // Get the cropped canvas
            const croppedCanvas = cropper.getCroppedCanvas();
            if (!croppedCanvas) return;
            
            // Calculate dimensions to center the image
            const scale = Math.min(
                canvas.width / croppedCanvas.width,
                canvas.height / croppedCanvas.height
            );
            
            const scaledWidth = croppedCanvas.width * scale;
            const scaledHeight = croppedCanvas.height * scale;
            const x = (canvas.width - scaledWidth) / 2;
            const y = (canvas.height - scaledHeight) / 2;
            
            // Draw the cropped image centered on the background
            ctx.drawImage(croppedCanvas, x, y, scaledWidth, scaledHeight);
            
            // Convert to JPEG with 0.9 quality
            const previewUrl = canvas.toDataURL('image/jpeg', 0.9);
            preview.src = previewUrl;
            previewContainer.classList.remove('hidden');

            // Show dimensions
            const dimensionsInfo = document.getElementById('dimensionsInfo');
            dimensionsInfo.textContent = `Dimensions: ${canvas.width} × ${canvas.height} pixels`;

            // Update download link
            downloadBtn.href = previewUrl;
            downloadBtn.download = `social-card-${aspectRatioValue.replace('.', '_')}.jpg`;
        }
    </script>
</body>
</html>
